from guaimain1 import Ui_Form
from guai2 import Ui_Form1
from guai3 import Ui_MainWindow2
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
import sys
# from PyQt5.QtWidgets import QApplication, QStackedLayout, QWidget
from PyQt5.QtWidgets import QApplication, QStackedLayout, QWidget
import requests
import tempfile
import shutil
import json
import time
from aliyunsdkcore.acs_exception.exceptions import ClientException
from aliyunsdkcore.acs_exception.exceptions import ServerException
from aliyunsdkcore.client import AcsClient
from aliyunsdkcore.request import CommonRequest
import oss2
import urllib.parse
import os

dbname = './database.db'  # 存储预设的数据库名字
presetTableName = 'commandPreset'  # 存储预设的表单名字
ossTableName = 'oss'
apiTableName = 'api'

class FrameHomePage(QWidget, Ui_Form1):
    def __init__(self):
        super().__init__()
        self.setupUi(self)
        self.oss_init()
        self.pushButton_2.clicked.connect(lambda: self.get_mp3_text(self.lineEdit.text()))
        self.pushButton.clicked.connect(lambda: self.get_mp3_file(self.textEdit.toPlainText()))
        # self.oss1 = AliOss()
        # self.pushButton_2.clicked.connect(self.oss1.get_mp3_text)

        # self.lineEdit

    def oss_init(self):
        # 地域ID，固定值。
        self.data1 = FrameBlogPage()
        # self.data1.setupUi(self)
        self.accessKeyId = self.data1.AccessKeyID_.text()
        self.accessKeySecret = self.data1.AcKeySecret.text()
        self.appKey = self.data1.AppKey.text()
        self.bucketName = self.data1.BuckyetName_.text()
        self.endpointDomain = self.data1.e1ndpoint.text()
        print(self.accessKeyId)
        self.REGION_ID = "cn-shanghai"
        self.PRODUCT = "nls-filetrans"
        self.DOMAIN = "filetrans.cn-shanghai.aliyuncs.com"
        self.API_VERSION = "2018-08-17"
        self.POST_REQUEST_ACTION = "SubmitTask"
        self.GET_REQUEST_ACTION = "GetTaskResult"
        self.enable_sample_rate_adaptive = 'enable_sample_rate_adaptive'

        # 请求参数
        self.KEY_APP_KEY = "appkey"
        self.KEY_FILE_LINK = "file_link"
        self.KEY_VERSION = "version"
        self.KEY_ENABLE_WORDS = "enable_words"
        # 是否开启智能分轨
        self.KEY_AUTO_SPLIT = "auto_split"
        # 响应参数
        self.KEY_TASK = "Task"
        self.KEY_TASK_ID = "TaskId"
        self.KEY_STATUS_TEXT = "StatusText"
        self.KEY_RESULT = "Result"
        # 状态值
        self.STATUS_SUCCESS = "SUCCESS"
        self.STATUS_RUNNING = "RUNNING"
        self.STATUS_QUEUEING = "QUEUEING"
        # self.home.pushButton_2.clicked.connect(self.get_mp3_text)
        # self.pushButton_2.clicked.connect(self.showQdailog)

        # 创建AcsClient实例

    def get_aliyun_secret(self):
        client = AcsClient(self.accessKeyId, self.accessKeySecret, 'cn-shanghai')
        request = CommonRequest()
        request.set_method('POST')
        request.set_domain('nls-meta.cn-shanghai.aliyuncs.com')
        request.set_version('2019-02-28')
        request.set_action_name('CreateToken')
        r = client.do_action_with_exception(request)
        r = json.loads(r.decode())
        return r['Token'].get('Id')

    def get_mp3(self, text, mp3_name):
        # 将得到的 文本转换为 mp3
        data = {
            'appkey': self.appKey,  # 语音合成项目里的appkey
            "text": text,  # 要语音合成的文字
            'token': self.get_aliyun_secret(),  # 上一步的鉴权秘钥
            'format': 'mp3',  # 合成语音的格式
            "sample_rate": "16000",  # 比特率
            "volume": '90',  # 音量
            "pitch_rate": '0',  # 语调
            "speech_rate": '-250',  # 语速
            "voice": self.mode_b  # 发音人 参数详见 https://help.aliyun.com/document_detail/84435.html
        }
        header = {
            "Content-Type": "application/json;charset=UTF-8"
        }
        # // nls - gateway.cn - shanghai.aliyuncs.com / ws / v1
        r = requests.post('https://nls-gateway.cn-shanghai.aliyuncs.com/stream/v1/tts', data=json.dumps(data),
                          headers=header)
        # print(base64.b64encode(r.content).decode())
        # return base64.b64encode(r.content).decode()

        # 创建
        with tempfile.NamedTemporaryFile(suffix='.mp3', delete=False) as file:
            print(r.content)
            file.write(r.content)
            tmpfile = file.name

        shutil.move(tmpfile, mp3_name)

    # def send_record(self,text):
    #     a = tts(text)

    def fileTrans(self, akId, akSecret, appKey, fileLink):
        # 语音装转换为 文本 得到文本
        # 创建AcsClient实例
        client = AcsClient(akId, akSecret, self.REGION_ID)
        # 提交录音文件识别请求
        postRequest = CommonRequest()
        postRequest.set_domain(self.DOMAIN)
        postRequest.set_version(self.API_VERSION)
        postRequest.set_product(self.PRODUCT)
        postRequest.set_action_name(self.POST_REQUEST_ACTION)
        postRequest.set_method('POST')
        # 新接入请使用4.0版本，已接入（默认2.0）如需维持现状，请注释掉该参数设置。
        # 设置是否输出词信息，默认为false，开启时需要设置version为4.0。
        task = {self.KEY_APP_KEY: appKey, self.KEY_FILE_LINK: fileLink, self.KEY_VERSION: "4.0",
                self.KEY_ENABLE_WORDS: False, self.enable_sample_rate_adaptive: True}
        # 开启智能分轨，如果开启智能分轨，task中设置KEY_AUTO_SPLIT为True。
        # task = {KEY_APP_KEY : appKey, KEY_FILE_LINK : fileLink, KEY_VERSION : "4.0", KEY_ENABLE_WORDS : False, KEY_AUTO_SPLIT : True}
        task = json.dumps(task)
        print(task)
        postRequest.add_body_params(self.KEY_TASK, task)
        taskId = ""
        try:
            postResponse = client.do_action_with_exception(postRequest)
            postResponse = json.loads(postResponse)
            print(postResponse)
            statusText = postResponse[self.KEY_STATUS_TEXT]
            if statusText == self.STATUS_SUCCESS:
                print("录音文件识别请求成功响应！")
                taskId = postResponse[self.KEY_TASK_ID]
            else:
                print("录音文件识别请求失败！")
                text1 = ''
                text2 = 0
                return text1, text2
        except ServerException as e:
            print(e)
        except ClientException as e:
            print(e)
        # 创建CommonRequest，设置任务ID。
        getRequest = CommonRequest()
        getRequest.set_domain(self.DOMAIN)
        getRequest.set_version(self.API_VERSION)
        getRequest.set_product(self.PRODUCT)
        getRequest.set_action_name(self.GET_REQUEST_ACTION)
        getRequest.set_method('GET')
        getRequest.add_query_param(self.KEY_TASK_ID, taskId)
        # 提交录音文件识别结果查询请求
        # 以轮询的方式进行识别结果的查询，直到服务端返回的状态描述符为"SUCCESS"、"SUCCESS_WITH_NO_VALID_FRAGMENT"，
        # 或者为错误描述，则结束轮询。
        statusText = ""
        while True:
            try:
                getResponse = client.do_action_with_exception(getRequest)
                getResponse = json.loads(getResponse)
                print(type(getResponse))
                print(getResponse)

                statusText = getResponse[self.KEY_STATUS_TEXT]
                if statusText == self.STATUS_RUNNING or statusText == self.STATUS_QUEUEING:
                    # 继续轮询
                    print(10111)

                    time.sleep(1)
                else:
                    # 退出轮询
                    break
            except ServerException as e:
                print(e)
            except ClientException as e:
                print(e)
        if statusText == self.STATUS_SUCCESS:
            print(getResponse['Result']['Sentences'])
            print("录音文件识别成功！")
            text1 = self.get_text(getResponse['Result']['Sentences'])
            text2 = 1
            return text1,text2
        else:
            print("录音文件识别失败！")
        text1 = ''
        text2 = 0
        return text1, text2

    def get_text(self, sentences):
        # 多段话时 合成一句话
        text = ''
        for i in sentences:
            text += i['Text']
        return text

    def getMp3Name(self, file_path):
        # 生成语音文件名
        file_name = os.path.basename(file_path)
        print(file_name)
        print(type(file_name))
        if file_name:
            mp3_name = self.mode_a + '_' + file_name
        else:
            mp3_name = self.mode_a + '.mp3'
        return mp3_name
    def getFileName(self, file_path):
        # destination 上传用的文件后缀
        # 确定本地音频文件名
        file_name = os.path.basename(file_path)
        # 确定当前日期
        localtime = time.localtime(time.time())
        print('localtime')
        print(type(localtime))
        year = localtime.tm_year
        month = localtime.tm_mon
        day = localtime.tm_mday
        # 用当前日期给 oss 文件指定上传路径
        destination = '%s/%s/%s/%s' % (year, month, day, file_name)
        return destination

    def auth1(self, bucketName, endpointDomain, accessKeyId, accessKeySecret):

        self.bucketName = bucketName
        self.endpointDomain = endpointDomain
        self.accessKeyId = accessKeyId
        self.accessKeySecret = accessKeySecret
        self.auth = oss2.Auth(self.accessKeyId, self.accessKeySecret)
        self.bucket = oss2.Bucket(self.auth, self.endpointDomain, self.bucketName)

    def create(self):
        # 这面这行用于创建，并设置存储空间为私有读写权限。
        self.bucket.create_bucket(oss2.models.BUCKET_ACL_PRIVATE)

    def upload(self, source):
        # 这个是上传文件到 oss
        # destination 上传文件到OSS时 的后缀名字
        # source 手机你要上传文件的路径
        # 返回远程文件的链接 用于语音识别
        destination = self.getFileName(source)

        self.bucket.put_object_from_file(destination, source)
        remoteLink = r'https://' + urllib.parse.quote(
            '%s.%s/%s' % (self.bucketName, self.endpointDomain, destination))
        return remoteLink

    def download(self, source, destination):
        # 以下代码用于将指定的OSS文件下载到本地文件：
        # source 从OSS下载文件时需要指定包含文件后缀在内的完整路径，例如abc/efg/123.jpg。
        # destination由本地文件路径加文件名包括后缀组成，例如/users/local/myfile.txt。
        self.bucket.get_object_to_file(source, destination)

    def delete(self, source):
        # destination 表示删除OSS文件时需要指定包含文件后缀
        destination = self.getFileName(source)
        self.bucket.delete_object(destination)
        print('已删除')

    def showQdailog(self):
        dailog = QDialog()
        button2 = QPushButton('未检测到文件路径', dailog)
        # text1 = QLine('文件正处在生成中呀', dailog)
        button2.clicked.connect(dailog.close)
        button2.move(50, 50)
        dailog.setWindowTitle('没有路径')
        # 模式状态，下 所有的控件 都不可用 除非将 对话框 关闭
        dailog.setWindowModality(Qt.ApplicationModal)

        dailog.exec()

    def get_mp3_text(self, text=None):
        print('------1111------')
        print(text)

        if text:
            print(text)

            self.auth1(self.bucketName, self.endpointDomain, self.accessKeyId, self.accessKeySecret)
            file_link = self.upload(text)
            # 将得到的 oss 链接 传给 语音装换方法 得到文本
            text1, text2 = self.fileTrans(self.accessKeyId, self.accessKeySecret, self.appKey, file_link)
            # 如果返回正确的 文本 就执行以下程序
            if text2:
                dailog = QDialog()
                button2 = QPushButton('文本已生成', dailog)
                # text1 = QLine('文件正处在生成中呀', dailog)
                button2.clicked.connect(dailog.close)
                button2.move(50, 50)
                dailog.setWindowTitle('文本')
                # 模式状态，下 所有的控件 都不可用 除非将 对话框 关闭
                dailog.setWindowModality(Qt.ApplicationModal)
                self.delete(text)
                self.textEdit.setText(text1)
                dailog.exec()

        else:
            self.showQdailog()

    def get_mp3_file(self, need_str):
        if need_str:
            dailog = QDialog()
            button2 = QPushButton('语音文件已生成', dailog)
            # text1 = QLine('文件正处在生成中呀', dailog)
            button2.clicked.connect(dailog.close)
            button2.move(50, 50)
            dailog.setWindowTitle('mp3')
            # 模式状态，下 所有的控件 都不可用 除非将 对话框 关闭
            dailog.setWindowModality(Qt.ApplicationModal)
            mp3_name = self.getMp3Name(self.lineEdit.text())
            print('---', mp3_name ,'---')
            print('---', type(mp3_name),'---')
            self.get_mp3(need_str, mp3_name)
            dailog.exec()

        else:
            self.showNotext()

    def showNotext(self):
        dailog = QDialog()
        button2 = QPushButton('没有文本啊', dailog)
        # text1 = QLine('文件正处在生成中呀', dailog)
        button2.clicked.connect(dailog.close)
        button2.move(50, 50)
        dailog.setWindowTitle('没有文本')
        # 模式状态，下 所有的控件 都不可用 除非将 对话框 关闭
        dailog.setWindowModality(Qt.ApplicationModal)

        dailog.exec()



class FrameBlogPage(QWidget, Ui_MainWindow2):
    def __init__(self):
        super().__init__()
        self.setupUi(self)
        # self.oss_init()






class MainWidget(QWidget, Ui_Form):
    """
    主窗口
    """
    def __init__(self):
        super().__init__()
        self.setupUi(self)
        # 实例化一个堆叠布局
        self.qsl = QStackedLayout(self.frame)
        # 实例化分页面
        self.home = FrameHomePage()
        self.blog = FrameBlogPage()
        # 加入到布局中
        self.qsl.addWidget(self.home)
        self.qsl.addWidget(self.blog)
        # 控制函数
        self.controller()

    def controller(self):
        self.pushButton.clicked.connect(self.switch)
        self.pushButton_2.clicked.connect(self.switch)
        # self.pushButton_contact.clicked.connect(self.switch)

    def switch(self):
        print('1')
        sender = self.sender().objectName()
        # 按钮的名字要一一对应
        index = {
            "pushButton": 0,
            "pushButton_2": 1,
            # "pushButton_contact": 2,
        }

        self.qsl.setCurrentIndex(index[sender])

    def close_conn(self):

        self.blog.conn.close()




if __name__ == '__main__':
    app = QApplication(sys.argv)
    main1 = MainWidget()

    main1.show()
    sys.exit(app.exec_())
    # main1.close_conn()

